package ltd.hello.trik.aspectj;


import com.alibaba.fastjson.JSONObject;
import ltd.hello.trik.annotation.Log;
import ltd.hello.trik.model.LogEntity;
import ltd.hello.trik.model.Wxuser;
import ltd.hello.trik.service.LogService;
import ltd.hello.trik.service.WxuserService;
import ltd.hello.trik.util.DateUtil;
import ltd.hello.trik.utils.ServletUtils;
import ltd.hello.trik.utils.ip.IpUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author houzw
 *
 */
@SuppressWarnings("unused")
@Aspect
@Component
public class LogAspect {
	static Logger log= LogManager.getLogger(LogAspect.class);

	@Autowired
	private LogService logService;
	@Autowired
	private WxuserService usersService;

	@Pointcut("@annotation(ltd.hello.trik.annotation.Log)")
	public void logPointCut() {
	}

	// @After(value = "logPointCut()")
	@Around("logPointCut()")
	public Object after(ProceedingJoinPoint point) throws Throwable {
		long beginTime = System.currentTimeMillis();
		// 执行方法
		Object result = point.proceed();
		// 执行时长(毫秒)
		long time = System.currentTimeMillis() - beginTime;

		saveLog(point, time);
		return result;
	}

	private Map<String,Object> getParams(ProceedingJoinPoint point){
		Signature signature = point.getSignature();
		Object[] objects =point.getArgs();
		Map<String,Object> map=new HashMap<>();
		if (objects==null||objects.length==0)return map;
		if (signature instanceof MethodSignature) {
			MethodSignature methodSignature = (MethodSignature) signature;
			String[] properties = methodSignature.getParameterNames();
			if (properties != null) {
				for (int i = 0; i < properties.length; i++) {
					map.put(properties[i], objects[i]);
				}
			}
		}
		return map;
	}


	private void saveLog(ProceedingJoinPoint joinPoint, long time) {
		try {
			MethodSignature signature = (MethodSignature) joinPoint.getSignature();
			Method method = signature.getMethod();
			LogEntity sysLog = new LogEntity();
			Log syslog = method.getAnnotation(Log.class);
			if (syslog != null) {
				// 注解上的描述
				sysLog.setOperation(syslog.value());
			}
			// 请求的方法名
			String className = joinPoint.getTarget().getClass().getName();
			String methodName = signature.getName();
			sysLog.setMethod(className + "." + methodName + "()");
			 //请求的参数
//			 Object[] args = joinPoint.getArgs();
//			 StringBuilder params = new StringBuilder();
//			 for (int i = 0; i < args.length; i++) {
//			 	params.append(JSONUtils.beanToJson(args[i])).append(",");
//			 	System.out.println(args[i]);
//			 }
			Map<String,Object> map=getParams(joinPoint);
			 String params=new JSONObject(map).toString();
			 sysLog.setParams(params);
			Wxuser wxuser=null;
			 try {
				wxuser = usersService.selectByOpenId(map.get("openid").toString());
			 }catch (Exception e){}
			if (wxuser != null) {
				sysLog.setUsername(wxuser.getNickName());
				sysLog.setUserid((long)wxuser.getId());
				sysLog.setOpenid(wxuser.getOpenid());
			}else {
				sysLog.setUserid(-1L);
				sysLog.setUsername("获取用户信息为空");
			}


			// 获取request
			HttpServletRequest request = ServletUtils.getRequest();
			// 设置IP地址
			sysLog.setIp(IpUtils.getIpAddr(request));
			// 用户名

//			// ---------------
//			HttpSession session = SysContent.getSession();
////			HttpServletRequest httpServletRequest = SysContent.getRequest();
////			Wxuser user = (Wxuser) httpServletRequest.getSession().getAttribute("user");
//			Wxuser user = (Wxuser) session.getAttribute("user");
//			if (user != null) {
//				sysLog.setUserid((long) user.getId());
//				sysLog.setUsername(user.getName());
//				sysLog.setParams(user.getOpenid());
//			} else {
//				ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
//						.getRequestAttributes();
//				HttpServletRequest req = requestAttributes.getRequest();
//				HttpServletResponse res = requestAttributes.getResponse();
//				// 从session里面获取对应的值
//				Wxuser currUser = (Wxuser) requestAttributes.getAttribute("user", RequestAttributes.SCOPE_SESSION);
//				// ---------------
//
//				// Users currUser = (Users)
//				// request.getSession().getAttribute("user");
//				if (null == currUser) {
//					if (null != sysLog.getParams()) {
//						sysLog.setUserid(-1L);
//						sysLog.setUsername(sysLog.getParams());
//					} else {
//						sysLog.setUserid(-1L);
//						sysLog.setUsername("获取用户信息为空");
//					}
//				} else {
//					// sysLog.setUserid(Long.valueOf(currUser.getId()));
//					sysLog.setUserid((long) currUser.getId());
//					sysLog.setUsername(currUser.getName());
//					sysLog.setParams(currUser.getOpenid());
//				}
//			}

			sysLog.setTime(time);
			Date date = new Date();
			sysLog.setLogTime(DateUtil.date2Str(date));
			logService.save(sysLog);
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage(), e);
		}
		log.info("AOP method excute ！！！");
	}
}
